/*
 * MyFileReader 读取被请求的文件或列出目录下的内容
 * @author  Zhang Nan
 * @since [28/02/2017]
 *
 */

package io.tim.webserver.simple02.util;

import java.io.*;
import java.util.*;
import java.util.Date;

public class MyFileReader {

	private int nbRead;// 记录读取的字节数
	private byte[] buffer;// 定义一个字节缓冲区从文件中读取的内容
	private String Directory_Name = "";// 记录当前的目录名称
	private String MIME_TYPE = ""; // 记录被请求的文件的 mime type
	private final int CGI_PROG = 1;// 如果被请求的文件是 cgi 程序，则使用这个类型标识
	private final int PHP_PROG = 2;// 如果被请求的文件是 php 程序，则使用这个类型标识
	private String mailto = "timothyzhn@gmail.com";

	public MyFileReader() {
		nbRead = 0;
		buffer = new byte[1024];// 定义缓冲区容量 1 KB
	}

	public void setDirectory_Name(String Dir) {

		Directory_Name = Dir;
	}

	public String getDirectory_Name() {
		return Directory_Name;
	}

	/**
	 * 处理 404 Not Found
	 */

	void FileNotFound(OutputStream outS, String HOST_NAME) throws IOException {

		outS.write(new String("<html>\r\n").getBytes());
		outS.flush();
		outS.write(new String("<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> </head>")
				.getBytes());
		outS.flush();
		outS.write(new String("<Title>404 File Not Found</Title>\r\n").getBytes());
		outS.flush();
		outS.write(new String("<body bgcolor='grey'>\r\n").getBytes());
		outS.flush();
		outS.write(new String("<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>\r\n").getBytes());
		outS.flush();
		outS.write(new String("<div align='center'><center></p>\r\n").getBytes());
		outS.flush();
		outS.flush();
		outS.write(new String("<table border='1' width='700' bgcolor='black'><TR>\r\n").getBytes());
		outS.write(new String(
				"<td align='center'><p align='center'><font color='red' size='6'><strong>404 File Not Found</strong></font></p>"
						+ "<p align='left'><font color='#FFFFFF'><strong> Web Server 无法找到请求的文件或脚本"
						+ " 。请检查您的 URL，确保您输入的访问路径是正确的。如问题仍然存在请与系统管理员联系 " + "   <a href='mailto:>" + mailto + "'>"
						+ mailto + "</a></strong></font></p><p>&nbsp;</p></td></TR></Table>\r\n").getBytes());
		outS.flush();
		outS.write(new String("</center></div>\r\n").getBytes());
		outS.flush();
		outS.write(new String("</html>" + "\r\n").getBytes());
		outS.flush();
	}

	/**
	 * 发送代码为 200 的成功响应，通知客户端，其请求已经被接收并处理
	 */
	public void HttpResponseOK(OutputStream OUT_OK, File file, String file_mime) throws IOException {

		/** 测试文件类型以获取正确的 mime type 信息 **/

		Mimes mim = new Mimes();
		MIME_TYPE = mim.getMimes(file_mime);

		/**
		 * 发送类型为 200 的 Http Response
		 * 
		 * HTTP/1.x 200 OK + crlf Date : xx/xx/xxxx + crlf Server : serverName +
		 * crlf content-length : X bytes + crlf content-type : mime type + crlf
		 * 
		 */
		OUT_OK.write(new String("HTTP/1.1 200 OK\r\n").getBytes());
		OUT_OK.flush();
		OUT_OK.write(new String("Date: " + new Date().toString() + "\r\n").getBytes());
		OUT_OK.flush();
		OUT_OK.write(new String("Server: WebServer Simple02\r\n").getBytes());
		OUT_OK.flush();
		OUT_OK.write(new String("Accept-Ranges: bytes\r\n").getBytes());
		OUT_OK.flush();
		OUT_OK.write(new String("content-length: " + String.valueOf(file.length()) + "\r\n").getBytes());
		OUT_OK.flush();
		OUT_OK.write(new String("Content-Type: " + MIME_TYPE + "\r\n").getBytes());
		OUT_OK.flush();
		OUT_OK.write(new String("\r\n").getBytes());
		OUT_OK.flush();
	}

	public void ReadFile(String File_Name, String HOST_NAME, OutputStream printWriter, String file_mime_Type)
			throws IOException {
		System.out.println("File_Name: " + File_Name);
		File f = new File(File_Name);

		if (!f.exists()) {
			this.FileNotFound(printWriter, HOST_NAME);
		} else {
			if (f.canRead()) {
				FileInputStream fich = new FileInputStream(File_Name);

				this.HttpResponseOK(printWriter, f, file_mime_Type);

				/**
				 * 循环读取文件内容，并发送内容到客户端，直到文件末尾
				 */
				while ((nbRead = fich.read(buffer, 0, buffer.length)) != -1) {
					System.out.println(new String(buffer));
					printWriter.write(buffer, 0, nbRead);
					printWriter.flush();

				}
				fich.close();
			}
		}

	}

	/**
	 * 返回一个路径字符串中的最底层的目录名
	 * 
	 * @param Folder
	 * @return
	 */
	public String DirectoryToList(String Folder) {
		String ActualDirectory = "";
		String[] folderSet = Folder.split("/");
		int length = folderSet.length;
		if (length == 0) {
			return Folder;
		} else {
			ActualDirectory = folderSet[length - 1];
		}
		return ActualDirectory;
	}

	/**
	 * 显示目录路径中最后一个目录的内容
	 * 
	 * @param directory
	 * @param pr
	 * @param HOST_NAME_LINK
	 * @param Icons_Path
	 * @throws IOException
	 */
	public void ListDir(String directory, OutputStream pr, String HOST_NAME_LINK, String Icons_Path)
			throws IOException {

		File DIR_FILE = new File(directory);

		String File_Separ_String = System.getProperty("file.separator");
		String ActualDir = this.DirectoryToList(this.getDirectory_Name());

		if (DIR_FILE.isDirectory()) {

			pr.write(new String("<html><head><h1>" + HOST_NAME_LINK + "- /" + this.getDirectory_Name()
					+ "</h1></head><body><HR><BR>").getBytes());

			String[] File_List = new String[DIR_FILE.list().length];

			File_List = DIR_FILE.list();

			// 显示头行信息，包括名称、最后修改时间、大小

			pr.write(new String("<Table border=0>").getBytes());
			pr.write(new String("<TR>").getBytes());
			pr.write(new String("<TD width='50'> </TD>").getBytes());
			pr.write(new String("<TD><strong>Name</strong></TD>").getBytes());
			pr.write(new String("<TD align='center'><strong>Last Modified</strong></TD>").getBytes());
			pr.write(new String("<TD align='center' width='50'><strong>Size</strong></TD>").getBytes());
			pr.write(new String("</TR>").getBytes());

			for (int i = 0; i < File_List.length; i++) {

				pr.write(new String("<TR>").getBytes());

				if (new File(directory + File_Separ_String + File_List[i]).isDirectory()) {

					// 列出子目录

					if (File_List[i].equals("icons")) {
						pr.write(new String("<TD width='50'></TD>").getBytes());
						pr.write(new String("<TD></TD>").getBytes());
						pr.write(new String("<TD align='center' width='300'></TD>").getBytes());
						pr.write(new String("<TD align='center' width='50'></TD>").getBytes());
					} else {
						pr.write(new String(
								"<TD width='50'><img src=" + Icons_Path + "dir.gif width='22' height='22'></TD>")
										.getBytes());
						pr.write(new String("<TD><a href='" + ActualDir + '/' + File_List[i] + "'>" + File_List[i]
								+ "</a>" + "</TD>").getBytes());
						pr.write(new String("<TD align='center' width='300'>"
								+ new Date(new File(directory + File_Separ_String + File_List[i]).lastModified())
										.toString()
								+ "</TD>").getBytes());
						pr.write(new String(
								"<TD align='center' width='50'><font color=red><strong>&lt;DIR&gt;</strong></font></TD>")
										.getBytes());

					}

				}

				else {

					// 列出文件

					pr.write(new String(
							"<TD width='50'><img src=" + Icons_Path + "File.gif width='22' height='22'></TD>")
									.getBytes());

					pr.write(new String(
							"<TD><a href='" + ActualDir + '/' + File_List[i] + "'>" + File_List[i] + "</a>" + "</TD>")
									.getBytes());
					pr.write(new String("<TD  align='center' width='300'>"
							+ new Date(new File(directory + File_Separ_String + File_List[i]).lastModified()).toString()
							+ "</TD>").getBytes());
					pr.write(new String("<TD align='center' width='50'><font color=red><strong>"
							+ String.valueOf(new File(directory + File_Separ_String + File_List[i]).length())
							+ "</font></strong></TD>").getBytes());
				}
				pr.write(new String("</TR>").getBytes());

			}
		}
		pr.write(new String("</Table>" + "<Hr><BR>Web Server Simple02 at " + HOST_NAME_LINK + "</body></html>")
				.getBytes());

	}
}
